package services

import (
	"gin-study/app/dao"
	"gin-study/app/http/requests"
	"gin-study/app/models"
	"github.com/patrickmn/go-cache"
	"github.com/spf13/cast"
	"gorm.io/gorm"
	"strings"
	"time"
)

var User *user

func init() {
	User = &user{
		cache: cache.New(cache.NoExpiration, time.Minute),
	}
}

type user struct {
	cache *cache.Cache
}

func (this *user) GetUserById(id uint) (user *models.User, err error) {
	data, exists := this.cache.Get(cast.ToString(id))
	if exists {
		user = data.(*models.User)
		return
	}

	err = dao.User.Take(&user, id).Error
	this.cache.Set(cast.ToString(id), user, time.Minute)
	return
}

func (this *user) GetUserByToken(token string) (*models.User, error) {
	token = strings.TrimLeft(token, "Bearer ")
	return this.GetUserById(cast.ToUint(token))
}

func (this *user) GetUsers(keywords string, page *requests.Page) *models.Paginator {
	tx := dao.User.Scopes(
		dao.User.ScopeKeywords(keywords),
	).Order("id DESC")
	return dao.Paginate(tx, &[]models.User{}, page.Page, page.Limit)
}

func (this *user) CreateUser(req *requests.UserCreateReq) (user *models.User, err error) {
	user.Username = req.Username
	user.Password = req.Password
	user.Nickname = req.Nickname

	err = dao.User.Transaction(func(tx *gorm.DB) error {
		return tx.Save(user).Error
	})

	return
}

func (this *user) UpdateUser(userId uint, req *requests.UserUpdateReq) (user *models.User, err error) {
	//使用结构体更新,只会更新非零值字段
	//使用map批量更新会更新所有map选定字段
	user, err = this.GetUserById(userId)
	if err != nil {
		return
	}

	user.Username = req.Username
	user.Password = req.Password
	user.Nickname = req.Nickname

	err = dao.User.Where("id", userId).Updates(user).Error

	if err != nil {
		return
	}

	return
}

func (this *user) DeleteUser(id interface{}) {
	dao.User.Delete(models.User{}, id)
}
